package com.mzj.saas.mservice.property.service;

import com.mzj.saas.commons.ApiData;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.util.StringUtils;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.department.entity.Department;
import com.mzj.saas.mservice.department.repository.DepartmentRepository;
import com.mzj.saas.mservice.eligible.entity.DepartmentEnterpriseTagRef;
import com.mzj.saas.mservice.eligible.entity.DepartmentHierarchy;
import com.mzj.saas.mservice.eligible.repository.DepartmentEnterpriseTagRefRepository;
import com.mzj.saas.mservice.eligible.repository.DepartmentHierarchyRepository;
import com.mzj.saas.mservice.property.entity.ServiceUser;
import com.mzj.saas.mservice.property.repository.ServiceUserRepository;
import com.mzj.saas.mservice.property.vo.ServiceUserVO;
import com.mzj.saas.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ServiceUserService {
    private static final Logger log = LoggerFactory.getLogger(ServiceUserService.class);

    private static final String USER_COUNT = "SELECT COUNT(1) ";
    private static final String USER_COLUM = "SELECT u.id,u.`org_id` as orgId,u.name,u.`mobile`,u.`status`,u.`create_time` as createTime,p.orderNumber";
    private static final String USER_FROM_MONITOR = " FROM `saas_service_user` u\n" +
            "LEFT JOIN (\n" +
            "SELECT r.service_user_id AS serviceUserId, COUNT(r.id) AS orderNumber \n" +
            "FROM saas_estate_repairs_record r GROUP BY r.service_user_id \n" +
            ") p ON p.serviceUserId = u.id";
    private static final String ORDER = " ORDER BY create_time DESC";
    private static final String SQL_PAGE = " LIMIT ? OFFSET ?";

    @Autowired
    private RedisService redisService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ServiceUserRepository serviceUserRepository;
    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;

    private ServiceUserVO convertToVO(ServiceUser serviceUser) {
        ServiceUserVO serviceUserVO = new ServiceUserVO();
        serviceUserVO.setId(serviceUser.getId());
        serviceUserVO.setOrgId(serviceUser.getOrgId());
        departmentRepository.findById(serviceUser.getOrgId()).ifPresent(d -> serviceUserVO.setOrgName(d.getName()));
        serviceUserVO.setName(serviceUser.getName());
        serviceUserVO.setMobile(serviceUser.getMobile());
        serviceUserVO.setOrderNumber(serviceUser.getOrderNumber());
        serviceUserVO.setStatus(serviceUser.getStatus());
        serviceUserVO.setCreateTime(serviceUser.getCreateTime());

        return serviceUserVO;
    }
    /**
     * 维修人员列表
     * @param accessToken
     * @param serviceUserName 维修人员姓名
     * @param mobile 维修人电话
     * @param orderNumber 订单数量
     * @param pageNumber
     * @param pageSize
     * @return
     */
    public ResultBean<ApiData<ServiceUserVO>> list(String accessToken, String serviceUserName, String mobile,
                                                   Integer orderNumber, Integer pageNumber, Integer pageSize) {
        ResultBean<ApiData<ServiceUserVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<ServiceUserVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            //校验登录信息
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null) {
                return ResultBean.failedResultOfToken();
            }
            Long enterpriseId = token.getEnterpriseId();

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where u.status = 1 and u.org_id = ?");
            args.add(enterpriseId);

            if (!StringUtils.isEmpty(serviceUserName)) {
                where.append(" AND u.`name` = ?");
                args.add(serviceUserName);
            }

            if (!StringUtils.isEmpty(mobile)) {
                where.append(" AND u.`mobile` = ?");
                args.add(mobile);
            }

            //订单数
            if (orderNumber != null) {
                if (orderNumber == 0) {
                    where.append(" AND p.`orderNumber` is null");
                } else {
                    where.append(" AND p.`orderNumber` = ?");
                    args.add(orderNumber);
                }
            }

            // 总记录数
            Long total = jdbcTemplate.queryForObject(USER_COUNT + USER_FROM_MONITOR + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }

            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<ServiceUserVO> list = jdbcTemplate.query(USER_COLUM + USER_FROM_MONITOR + where + ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(ServiceUserVO.class), args.toArray());

            // 查询物业名称
            List<Long> orgIds = list.stream().filter(vo -> vo.getOrgId() != null).map(ServiceUserVO::getOrgId).distinct().collect(Collectors.toList());
            if (!orgIds.isEmpty()) {
                Map<Long, String> map = departmentRepository.findByIdIn(orgIds).stream().collect(Collectors.toMap(Department::getId, Department::getName));
                if (!map.isEmpty()) {
                    list.forEach(vo -> vo.setOrgName(map.get(vo.getOrgId())));
                }
            }

            /*//维修订单数量
            List<Long> ids = list.stream().map(vo -> vo.getId()).collect(Collectors.toList());
            Map<Long, List<EstateRepairsRecord>> map = estateRepairsRecordService.findByServiceUserIdIn(ids).stream().
                    collect(Collectors.groupingBy(EstateRepairsRecord::getServiceUserId));
            if (!map.isEmpty()) {
                for (ServiceUserVO vo : list) {
                    List<EstateRepairsRecord> records = map.get(vo.getId());
                    if (records != null && !records.isEmpty()) {
                        vo.setOrderNumber(records.size());
                    }
                }
            }*/

            apiData.setData(list);
            apiData.setTotal(total);

            resultBean.setResultData(apiData);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        resultBean.setResultData(apiData);
        return resultBean;
    }

    /**
     * 新增/编辑维修人员
     *
     * @param accessToken
     * @param serviceUserVO
     * @return
     *
     * 新增或修改时手机号不可重复
     */
    public ResultBean<ServiceUserVO> save(String accessToken, ServiceUserVO serviceUserVO) {
        try {
            //校验登录信息
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null)
                return ResultBean.failedResultOfToken();
            //企业id
            Long enterpriseId = token.getEnterpriseId();

            Long id = serviceUserVO.getId();
            String mobile = serviceUserVO.getMobile();

            DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
            if (hierarchy == null) {
                return ResultBean.failedResultWithMsg("用户所属机构未设置层级关系");
            }
            List<DepartmentEnterpriseTagRef> refs = departmentEnterpriseTagRefRepository.findByDepRefId(hierarchy.getId());
            List<Long> enterpriseTagIds = refs.stream().map(DepartmentEnterpriseTagRef::getTagId).distinct().collect(Collectors.toList());
            if (!enterpriseTagIds.contains(4L)) {
                return ResultBean.failedResultWithMsg("非物业公司，无法操作");
            }

            //新增
            if (id == null) {
                ServiceUser byMobile = serviceUserRepository.findByMobile(mobile);
                if (byMobile != null) {
                    return ResultBean.failedResultWithMsg("该号码已被添加");
                }

                ServiceUser serviceUser = new ServiceUser();
                serviceUser.setOrgId(enterpriseId);
                serviceUser.setName(serviceUserVO.getName());
                serviceUser.setMobile(serviceUserVO.getMobile());
                serviceUser.setOrderNumber(0);
                serviceUser.setStatus(1);
                serviceUser.setCreateTime(new Date());
                serviceUserRepository.save(serviceUser);
            }

            //编辑
            if (id != null) {
                Optional<ServiceUser> optional = serviceUserRepository.findById(id);
                ServiceUser serviceUser = optional.get();

                if (!mobile.equals(serviceUser.getMobile())) {
                    ServiceUser byMobile = serviceUserRepository.findByMobile(mobile);
                    if (byMobile != null) {
                        return ResultBean.failedResultWithMsg("该号码已被添加");
                    }
                }

                serviceUser.setOrgId(enterpriseId);
                serviceUser.setName(serviceUserVO.getName());
                serviceUser.setMobile(serviceUserVO.getMobile());
                serviceUserRepository.save(serviceUser);
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 删除维修人员
     *
     * @param accessToken
     * @param id 维修人员id
     * @return
     * 修改维修人员状态为删除
     */
    public ResultBean<Object> delete(String accessToken, Long id) {
        TokenRedisVo token = redisService.findTokenVo(accessToken);
        if (token == null)
            return ResultBean.failedResultOfToken();

        //修改维修人员状态
        String sql = "UPDATE saas_service_user SET status = 2 WHERE id = ?";
        int result = jdbcTemplate.update(sql, id);

        return result == 1 ? ResultBean.successfulResult(true) : ResultBean.failedResultOfParamWithMsg("删除失败");
    }

    public ServiceUser findById(Long serviceUserId) {
        return serviceUserRepository.findById(serviceUserId).orElse(null);
    }

    /**
     * 查询维修人员名单
     * @param accessToken
     * @return
     */
    public ResultBean<List<Map<String, Object>>> findServiceUser(String accessToken) {
        try {
            TokenRedisVo token = redisService.findTokenVo(accessToken);
            if (token == null) {
                return ResultBean.failedResultOfToken();
            }
            Long enterpriseId = token.getEnterpriseId();

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where u.status = 1 and u.org_id = ?");
            args.add(enterpriseId);

            List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT u.id,u.name FROM `saas_service_user` u" + where + ORDER
                    , args.toArray());

            return ResultBean.successfulResult(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}
